Top 10k strings from Programmierung der Z80 (19xx)(-)(de)(Part 2 of 3).z80 in <root> / bin / z80 / software / Sinclair Spectrum Collection TOSEC.exe / Sinclair ZX Spectrum - Utilities & Educational / Sinclair ZX Spectrum - Utilities & Educational - [Z80] (TOSEC-v2007-01-01) /

Back to the directory listing

   4 "1) den Inhalt der Adresse  hl","
   2 d$="00111100":
   2 d$="00011110":
   2 "1) Akku mit dem Byte  ( hl ) ver-","
   1 zur Adresse  de  bringen","2) de = de - 1","3) hl = hl - 1","4) bc = bc - 1":
   1 zur Adresse  de  bringen","2) de = de - 1","3) hl = hl - 1","4) bc = bc - 1","5) solange zu Punkt  1) springen,","
   1 zur Adresse  de  bringen","2) de = de + 1","3) hl = hl + 1","4) bc = bc - 1","5) solange zu","
   1 gleichen (Zero-Flag)","2) hl = hl - 1","3) bc = bc - 1":
   1 gleichen (Zero-Flag)","2) hl = hl + 1","3) bc = bc - 1":
   1 d$="popep m "
   1 d$="10011011":
   1 bis  bc = 0"
   1 b$="11010111":
   1 a$=a$+o$(n)+" ":
   1 a$=a$+b$(n)+" ":
   1 a$=a$+"Dazu folgendes Programm :":
   1 a$=a$+" Aber Doppelregister setzen das Zero-Flag schon auf eins, wenn eines der beiden Einzelregister bei Null angelangt ist. Also muessen wir mit  OR arbeiten, wie folgendes Beispiel zeigt :":
   1 a$="und das Register- Bit = 1 sind.":
   1 a$="umwandeln, verwandelt er sich in den Befehl":
   1 a$="scf  bedeutet ""set carry-flag"" und setzt das Carry-Flag = 1.":
   1 a$="rst  "+
   1 a$="oder das Register- Bit = 1 ist.":
   1 a$="ld  a , ( ix + N )":
   1 a$="ld  a , ( hl )":
   1 a$="koennen dann anhand des Carry-Flags Entscheidungen treffen.":
   1 a$="das bewirkt der Befehl  rr ":
   1 a$="ccf  bedeutet ""complement carry-flag"" und negiert das Carry-Flag.":
   1 a$="Zum Verdoppeln, sowie Halbieren eines Registerinhaltes, wobei das Carry-Flag beim Verdoppeln anzeigt, ob ein Ueberlauf stattfand, und beim Halbieren, ob die Zahl nicht mehr durch 2 teilbar war.":
   1 a$="Zuerst wird die Bitreihe verschoben. Das rechteste Bit rutscht ins Carry-Flag und gleichzeitig in die Luecke auf der linken Seite. Das bedeutet, dass nach achtmaligem Ausfuehren dieser Funktion das Byte wie vorher vorliegt.":
   1 a$="Wuerden wir jetzt das Byte nocheinmal zusammenrechnen, so kaemen wir auf  30 . Wie Sie sehen, hat sich der Inhalt des Akkus durch den Befehl  srl  halbiert. Beachten Sie, dass das Carry-Flag in diesem Falle Null geworden ist. Die Befehle":
   1 a$="Wir wollen uns dafuer ein Programm ansehen, was den SCREEN des Spectrum invertiert. Der Bildspeicher faengt ab Adresse 16384 an und hat die Laenge von 6144 Bytes. Also muessen wir eine Schleife haben, die von 6144 auf 0 zurueckzaehlt und dabei das hl-Register (anfangs 16384) immer um 1 erhoeht."
   1 a$="Wir wollen auf der naechsten Seite ein paar Anwendungsprogramme fuer die Operation OR in Verbindung mit  cpl  sehen.":
   1 a$="Wir hatten schon die Befehle adc  und  sbc  kurz besprochen, als wir ueber die 237er-Gruppe redeten. Der Befehl  adc  a , b z.B. addiert zum Akku zuerst das b-Register und zusaetzlich den Inhalt des Carry-Flags. Das bedeutet, wenn  a = 10 ist, und b = 5 , so erhalten wir, wenn das Carry-Flag Null ist, als Ergebnis  15."
   1 a$="Wie wir wissen, benoetigt ein  call NN - Befehl  3 Bytes. Das ist fuer Z80-Verhaeltnisse relativ viel. Um etwas Speicherplatz sparen zu koennen, wurde der RST - Befehl ( Restart ) eingefuehrt. Es gibt acht verschiedene RST-Befehle, die genau die selbe Wirkung wie call-Befehle haetten. Es gibt :":
   1 a$="Wie arbeitet man mit dem Befehl  rst 16  ?":
   1 a$="Wie Sie wissen, bedeutet die Klammer ""den Inhalt"" einer Adresse oder Variablen. Da man mit dem Befehl  ld  a , ( NN )  das Byte ab Adresse NN in den Akku laden kann, kann man z.B. mit dem Befehl  ld  hl , ( NN ) das l-Register mit dem Byte an Adresse NN, sowie das h-Register mit dem Byte, das an Adresse  NN+1 steht, laden.":
   1 a$="Wichtig sind diese Befehle zum Bestimmen vom Vorzeichen eines Ergebnisses einer Summe oder Subtraktion.":
   1 a$="Wichtig dabei ist, dass vor jedem rst-Befehl alle Register, die benutzt werden, mit push gerettet werden."
   1 a$="Wenn wir z.B. den Befehl":
   1 a$="Wenn wir also den Akku  AND  ein anderes Byte oder Register verknuepfen wollen, so muessen wir, um das Ergebnis zu erhalten, Bit fuer Bit verknuepfen. Das Ergebnis wandert wieder in den Akku.":
   1 a$="Wenn Sie irgendeinen  ix, iy - Befehl im Anhang C des Handbuches suchen, dann finden Sie lediglich zwei Codes, naemlich":
   1 a$="Weitere Befehle in dieser Gruppe sind  adc  (add with carry) und  sbc  (subtract with carry). Adc und Sbc tun genau dasselbe wie add und sub, sie addieren oder subtrahieren jeweils noch das Carry-Flag mit. Da es z.B. keinen  sub hl , de -Befehl gibt, muessen Sie den Befehl  sbc hl , de dafuer verwenden.Solange das Carry-Flag nicht 1 ist, aendert das am Ergebnis nichts.":
   1 a$="Was als Dezimalzahl 60 bedeutet. Wenn wir das ganze Byte um ein Bit nach rechts verschieben wollten, wuerden wir den Befehl  srl  verwenden. Nach dem Rollvorgang entsteht auf der linken Seite eine Luecke. In diese Luecke rutscht eine Null. Da auf der rechten Seite ein Bit verschwindet, rutscht dieses Bit in das Carry-Flag, wo es von den Bedingungsbefehlen  call, jr, jp und ret abgefragt werden kann.":
   1 a$="W e i t e r e   F l a g s":
   1 a$="Und der Befehl  cpd macht dies :":
   1 a$="Stoppen Sie auch jetzt das Tonband und lassen es in dieser Stellung stehen !":
   1 a$="Starten Sie das Tonband !":
   1 a$="So auch in Maschinencode. Man laedt dazu die Kanalnummer in den Akku und ruft dann die  ROM-Routine  ab 5633 auf.":
   1 a$="Seite "+
   1 a$="Sehen wir uns als Beispiel folgendes kleines Programm an, was den Bildschirmspeicher (ab 16384) ins RAM (ab 32768) kopiert :":
   1 a$="Sehen Sie auch dazu eine Graphik :":
   1 a$="R R C  und  R L C":
   1 a$="Praegen Sie sich vor allen Dingen die Codes von LDIR und LDDR ein, denn sie sind sehr wichtig !":
   1 a$="Praegen Sie sich bitte die folgenden Tabellen fest ein. Sie zeigen die logischen Verknuepfungen and, or und xor bezogen auf einzelne Bits :":
   1 a$="PRINT AT 0 , 0 ;":
   1 a$="Nocheinmal kommen wir zur 237er-Gruppe zurueck, um den Befehl  NEG  zu erklaeren.":
   1 a$="Nehmen wir an, wir wollen den ganzen Bildschirm mit dem Buchstaben  E  auffuellen. Dazu nehmen wir den ASCII-Code vom ""E"" (69), sowie die Anzahl der Buchstaben, die auf den Bildschirm passen (704). "
   1 a$="Nehmen wir an, der Inhalt unseres Akkus saehe so aus :":
   1 a$="Nebenbei lernen Sie ein neues Flag kennen. Es wird Carry-Flag ( C-Flag ) genannt. Viele Befehle benutzen es, und daher ist es so wichtig. Bei den 8-Bit-Verschiebebefehlen wird es als Zwischenspeicher fuer ein ""herausgerolltes"" Bit verwendet.":
   1 a$="Neben den Registerpaaren  bc, de, hl und sp  gibt es noch die zwei Indexregister  ix  und  iy. Mit ihnen ist es moeglich, eine Art eindimensionale Matrix ( = Array ) abzufragen. Lediglich die Codierung ist hier etwas schwieriger :":
   1 a$="Neben den Flags  Z  und  C  gibt es noch die Bedingungen  Po , Pe , P  und  M .":
   1 a$="NEG  bedeutet ""negate accumulator"" , d.h., der Akku wird von 256 abgezogen. Das Ergebnis wandert wieder in den Akku. Der Befehl  cpl  (complement accu), der den Code 47 hat, negiert den Akku, indem er ihn von 255 abzieht. Der Befehl daa (decimal adjust accu) prueft zuerst, ob der Akku > 159 ist. Wenn ja, zieht er 160 ab. Danach wird  6 dazuaddiert. Zu diesen 3 Befehlen nochmal eine Uebersicht :"
   1 a$="Moechten Sie hier auch Druckerauszuege von jeder Seite ?  ( ja / nein )":
   1 a$="Jeder dieser drei Befehle kann jedes der Einzelregister  a, b, c, d, e, h, l  und  (hl) als Operand haben. Wichtig ist, dass sich auch hier wieder alles auf den Akkumulator stuetzt. Also bedeutet die Operation  and  e  --> a  and  e .":
   1 a$="Jeder Zeichencode kommt in den Akku. Mit rst 16 wird er auf den Bildschirm gedruckt. Und so sieht dann ein PRINT AT 0,0;  in Maschinencode aus (naechste Seite) :"
   1 a$="Ist das Carry-Flag jedoch eingeschaltet, so erhalten Wir als Ergebnis  10 + 5 + 1 = 16.":
   1 a$="In einem Programm ist das jedoch nur einmal noetig.":
   1 a$="In diese bc-Schleife koennen wir nun unsere Invertierbefehle einsetzten. Dafuer holt der Befehl  ld  a , ( hl )  sich das laufende Bildschirmbyte in den Akku. Danach invertiert der Befehl  cpl  den Akku, so dass dann das veraenderte Byte zurueck an seinen Bildschirmplatz kann.":
   1 a$="Hier sind auch diese Befehle mit ihren Codes aufgelistet :":
   1 a$="Folglich endet es erst mit ret z, wenn das b-Register und das c-Register = Null sind.":
   1 a$="Es gibt sogar Befehle, die direkt das Carry-Flag ansprechen :  scf  und  ccf .":
   1 a$="Es gibt noch zwei derartige Befehle, die tatsaechlich ein Byte ohne Bitverlust rollen koennen. Sie heissen  rrc  und  rlc  (roll right circular  und  roll left circular).":
   1 a$="Es gibt aber auch noch ein paar andere Bit-Schiebebefehle. Z.B.  rr  und  rl  (roll right und roll left).":
   1 a$="Er tut folgendes :":
   1 a$="Einige davon koennen wir fuer uns selbst benutzen. Hier sind diese mit ihren Bedeutungen aufgelistet :":
   1 a$="Eine weitere wichtige Befehlsart in der 203er-Gruppe sind die 8-Bit-Verschiebebefehle. Mit ihnen kann man die 8 Bits eines beliebigen Registers entweder nach links oder nach rechts verschieben.":
   1 a$="Eine weitere Gruppe von Blckbefehlen ist die cp-Gruppe. Auch sie umfasst vier Befehle, mit denen es moeglich ist, ein Byte im Speicher zu suchen.":
   1 a$="Ein ueblicher Befehl, der denn Akku auf Null setzt, ganz egal, was im Akku steht, lautet  xor a .":
   1 a$="Druecken Sie jetzt eine Taste ..."
   1 a$="Dieser Befehl verdoppelt also den Inhalt eines Registers. Aber wozu kann man diese beiden Befehle benutzen ?":
   1 a$="Dieser Befehl kann immer nur ein ASCII-Zeichen drucken. Fuer PRINT AT  muessen wir z.B. den ASCII-Code 22 gefolgt von den Koordinaten als ASCII-Zeichen.":
   1 a$="Diese zwei Codes sagen der Z80 naemlich, dass der naechste Befehl auf ix, bzw. iy  bezogen ist.":
   1 a$="Diese springen zu den Adressen, die im Befehl stehen. Diese Adressen liegen im ROM-Bereich und dort stehen wichtige Routinen, die das ROM benutzt."
   1 a$="Die zwei Grafiken auf der naechsten Seite veranschaulichen das sehr gut.":
   1 a$="Die Funktion  XOR  (= exclusive or) setzt das Ergebnis-Bit nur dann 1 , wenn das Akku-Bit ungleich dem Register-Bit ist.":
   1 a$="Die Codes fuer die Blocktransferbefehle lauten :":
   1 a$="Die Codes der Befehle  srl , sla , rr und rl :":
   1 a$="Die Blocktransferbefehle koennen sehr viele Dinge auf einmal tun, und das auch noch blitzschnell. Man kann hier nichts anderes tun, als aufzulisten, was diese Befehle im Einzelnen tun. Nehmen wir zuerst den Befehl  LDI :":
   1 a$="Die 237er-Gruppe umfasst zwar sehr wenige, dafuer aber sehr leistungsfaehige Befehle. Aber zuerst sehen wir uns die 8 Ld-Befehle mit ihren Codes an :":
   1 a$="Des weiteren gibt es den  LDIR  und den  LDDR -Befehl. Der LDIR-Befehl tut das :":
   1 a$="Der Gegenbefehl dazu sieht logischerweise so aus :":
   1 a$="Der Befehl cpi tut folgendes :":
   1 a$="Der Befehl  sla  tut genau dasselbe wie  srl, nur in der anderen Richtung. Er verschiebt das angegebene Register um ein Bit nach links, wobei diesmal das linkeste Bit ins Carry-Flag wandert. Auf der rechten Seite rutscht eine Null hinein.":
   1 a$="Der Befehl  LDD  hingegen tut das :":
   1 a$="Der  sbc-Befehl geht genauso vor; er zieht vom Akku zusaetzlich noch das Carry-Flag ab.":
   1 a$="Den letzten Bit-Schibebefehl, den Sie wissen muessen, heisst  sra . Er verschiebt die Bits nach rechts und auch hier wandert das rechteste Bit ins Carry-Flag. Das linkeste Bit (Bit 7) wird allerdings nach dem Verschieben selbst nocheinmal in die Luecke gesetzt. Die Grafik zeigt es naeher :":
   1 a$="Demnach macht der  LDDR-Befehl das :":
   1 a$="Das waeren also die beruechtigten Schiebebefehle der 203er-Gruppe. Damit waere die 203er-Gruppe abgeschlossen, so dass wir uns jetzt den Befehlen der 237er-Gruppe widmen koennen.":
   1 a$="Das liegt daran, dass hier der Akku mit sich selbst verknuepft wird und durch xor alle Bits des Ergebnisses auf Null gesetzt werden. and  a  und  or  a  veraendern den Akku nicht.":
   1 a$="Das kann man also auf alle  hl-bezogenen Befehle in dieser Art anwenden, bis auf die Befehle, in denen  hl in Klammern steht.":
   1 a$="Das ist der zweite Teil unseres Maschinensprache-Kurs. Wir hatten uns zuletzt mit den Bit-veraenderungs- und -Abfragebefehlen   set , res  und bit beschaeftigt.":
   1 a$="Das fertige Programm sieht dann so aus :":
   1 a$="Das bedeutet, dass jeder Befehl, der ein  ( hl ) innehat, noch eine weitere Zahl erwartet. Das ist eine 1-Byte-Zahl zwischen 0 und 255. Also laedt der Akku mit diesem Befehl das Byte, das an Adresse ( ix + N ) steht."
   1 a$="Das Ergebnis-Bit wird bei der Funktion AND also nur dann 1 , wenn das Akku-Bit  und":
   1 a$="Das Carry-Flag und der Akkumulator":
   1 a$="Damit wollen wir erst einmal die 237er-Gruppe verlassen und zum normalen Befehlssatz zurueckkehren. Wir werden jetzt etwas ueber die logischen Operationen  AND  OR  und  XOR  erfahren. Glauben Sie bloss nicht, dass es so einfach wie in BASIC ist.":
   1 a$="Dafuer gibt es folgende Befehle mit ihren Codes :"
   1 a$="Dabei werden alle hl-Register in dem Befehl zu ix, bzw. iy umgewandelt. Als Beispiel nehmen wir  ld  hl , 1000 . Wenn wir nun den Code 221 vor diesen Befehl setzen, verwandelt er sich in  ld  ix , 1000.":
   1 a$="D i e   R e s t a r t  -  B e f e h l e  :":
   1 a$="D i e   I n d e x r e g i s t e r":
   1 a$="D i e   2 3 7 e r - G r u p p e":
   1 a$="Code":
   1 a$="Bevor man zum ersten Male etwas druckt, sollte man dem Computer sagen, in welchen Bildschirmberiech er drucken soll. Im BASIC  druckt er immer im Bereich  # 2 . Fuer den unteren Bereich gibt man dann entweder  # 0  oder  # 1  an.":
   1 a$="Bei der Funktion  OR  dagegen wird das Ergeb- nis-Bit 1 , wenn das Akku-Bit oder":
   1 a$="Befehl":
   1 a$="Beachten Sie,dass alle diese Codes in der 203er Gruppe stehen und deshalb die Zahl 203 vorangestellt werden muss.":
   1 a$="B l o c k t r a n s f e r b e f e h l e":
   1 a$="Auch hier gibt es natuerlich automatische Blockbefehle, sie heissen  cpir  und  cpdr . Sie tun auch hier dasselbe wie cpi und cpd, nur, dass sie das solange tun, bis entweder der  Akku gleich dem Byte  ( hl ) ist, oder  bc=0 ist.":
   1 a$="Auch diese beiden Befehle verschieben in gleicher Weise ein beliebiges Register, nur gibt es keine Luecken , denn auf der einen Seite rutscht das Carry-Flag hinein, waehrend auf der anderen Seite das ""herausgerollte"" Bit wieder ins Carry-Flag rutscht.":
   1 a$="Auch dazu wieder ein Beispiel :":
   1 a$="Am nuetzlichsten davon ist  rst 16  fuer uns. Denn damit ist es moeglich, genauso, wie im BASIC  mit PRINT zu arbeiten.":
   1 a$="Aber dazu spaeter. Sehen wir uns zuerst einmal an, wie ein Register vorher und hinterher aussieht.":
   1 a$="Aber auch zum Rollen des Bildschirminhaltes lassen sich diese beiden Befehle gut nutzen, wie Sie spaeter sehen werden.":
   1 a$="= Register/Zahl":
   1 a$="= Akkumulator":
   1 a$="= Akku nachher":
   1 a$="3) Die Bedingung  P trifft zu, wenn die zuletzt ausgefuehrte Operation zu einer positive Zahl fuehrte, die Bedingung M hingegen, wenn die Zahl negativ war.":
   1 a$="253  prefixes instructions using  iy":
   1 a$="221  prefixes instructions using  ix":
   1 a$="2) Die Bedingung Pe  bedeutet ""parity even"" (gerade) und trifft zu, wenn die zuletzt ausgefuehrte Operation eine gerade Zahl lieferte,":
   1 a$="1) Die Bedingung Po  bedeutet ""parity odd"" (ungerade)  und trifft zu, wenn die zuletzt ausgefuehrte Operation eine ungerade Zahl lieferte.":
   1 a$="( Bei laengeren Texten rate ich jedoch zur Verwendung einer Schleife )":
   1 a$="( Alle fuer ix beschriebenen Dinge treffen natuerlich auch auf  iy  zu ).":
   1 a$=" Druecken Sie jetzt bitte eine beliebige Taste...":
   1 Punkt 1) springen, bis bc = 0"
   1 Druecken Sie jetzt eine Taste ...
   1 ,"b","c","d","e","h","l","( hl )","a","sla ",32
   1 ,"b","c","d","e","h","l","( hl )","a","rr ",24
   1 ,"b","c","d","e","h","l","( hl )","a","rl ",16
   1 ,"b","c","d","e","h","l","( hl )","a"
   1 "sbc  hl , bc","237 , 66","adc  hl , bc","237 , 74","sbc  hl , de","237 , 82","adc  hl , de","237 , 90","sbc  hl , hl","237 , 98","adc  hl , hl","237 , 106","sbc  hl , sp","237 , 114","adc  hl , sp","237 , 122"
   1 "rst  0","entspricht  NEW in BASIC","rst  16","entspricht PRINT in BASIC","rst 24","liest das naechte zu interpretierende","
   1 "ret  x ","jp  x , NN","call  x , NN"
   1 "ldi","237 , 160","ldd","237 , 168","ldir","237 , 176","lddr","237 , 184":
   1 "ld  ( NN ) , bc","237 , 67","ld  bc , ( NN )","237 , 75","ld  ( NN ) , de","237 , 83","ld  de , ( NN )","237 , 91","ld  ( NN ) , hl","237 , 99","ld  hl , ( NN )","237 , 107","ld  ( NN ) , sp","237 , 115","ld  sp , ( NN )","237 , 123"
   1 "jr  c , DIS","jr  nc , DIS","jp  c , NN","jp  nc , NN","call  c , NN","call  nc , NN","ret  c","ret  nc"
   1 "Befehl","Codes","Aufgabe","neg","237 , 68","a = 256 - a","cpl","47","a = 255 - a","daa","39","1) wenn a > 160 , a = a - 160","
   1 "Adresse","Befehle","Codes","x","40000","ld  hl , 16384","33 , 0 , 64","40003","ld  bc , 6144","1 , 0 , 24","40006","ld  a , ( hl )","126","40007","cpl","47","40008","ld  ( hl ) , a","119","40009","dec  bc","11","40010","ld  a , b","120"
   1 "40022","or  c","177","40023","jr  nz , ","32 , 246","40025","ret","201"
   1 "40011","or  c","177","40012","ret  z","200","40013","inc  hl","35","40014","jr","24 , 246"
   1 "40008","xor  a","175","40009","rst  16","215","40010","xor  a","175","40011","rst 16","215","40012","ld  bc , 704","1 , 192 , 2","40015","ld  a , 69","62 , 69","40017","push  bc","197","40018","rst  16","215","40019","pop  bc","193","40020","dec  bc","11","40021","ld  a , b","120"
   1 "40000","ld  hl , 16384","33 , 0 , 64","40003","ld  de , 32768","17 , 0 , 64","40006","ld  bc , 6912","1 , 0 , 27","40009","ldir","237 , 176","40011","ret","201":
   1 "40000","ld  a , 22","62 , 22","40002","rst  16","215","40003","ld  a , 0","62 , 0","40005","rst  16","215","40006","ld  a , 0","62 , 0","40008","rst  16","215"
   1 "40000","ld  a , 2","62 , 2","40002","call  5633","205 , 1 , 22","40005","ld  a , 22","62 , 22","40007","rst  16","215"
   1 ",a$,"ret z","
   1 ",a$,"or  c","
   1 ",a$,"ld  bc , 6144","
   1 ",a$,"ld  a , b","
   1 ",a$,"dec  bc","
   1 ",a$,"2) a = a + 6"
   1 ",a$,". . . . . . .","
   1 ","ld  hl , 16384","
   1 ","Zeichen im BASIC-Programm"
   1   zur Adresse  de  bringen","2) de = de + 1","3) hl = hl + 1","4) bc = bc - 1"